using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using Canvas.Scripts.ImageRotate;
using Nsb.Classes;
using jQueryApi;

namespace WhirliGig.Classes
{
    [IgnoreNamespace]
    public class Gig : Actor
    {
        public string Id;
        public jQueryObject Content;
        public static readonly Dictionary<string, int> DeefCss = new Dictionary("padding-top", 8, "padding-left", 16);
        public const string GigClassName = "Gig";
        public const string DotGigClassName = "." + GigClassName;
        public const string GigContentClassName = "GigC";
        public const string DotGigContentClassName = "." + GigContentClassName;

        public Gig()
        {
            Element = jQuery.FromHtml("<div class='Gig'/>");
            SetId(Formulas.NewId);
        }

#pragma warning disable 108,114

        public virtual void Draggable(Dictionary opt, jQueryEventHandler doneFn)
        {
            //return (GigEdit) this;
        }

        [AlternateSignature]
        public extern Gig AppendTo(string sel);

        public Gig AppendTo(jQueryObject el)
        {
            Element.AppendTo(el);
            return this;
        }

        public Gig AddClass(string cls)
        {
            if (!String.IsNullOrEmpty(cls))
                Element.AddClass(cls);
            return this;
        }

        public Gig AddAttr(Dictionary attr)
        {
            if (attr != null && attr.Count > 0)
                Element.Attribute(attr);
            return this;
        }

        public Gig AddCss(Dictionary css)
        {
            if (css != null && css.Count > 0)
                Element.CSS(css);
            return this;
        }

        public Gig AddType(string type)
        {
            if (!String.IsNullOrEmpty(type))
                Element.Data("gigType", type);
            return this;
        }

        public Gig AddHasHeight(bool has)
        {
            Element.Data("gigHasHeight", has);
            return this;
        }

        public Gig AddTilt(double deg)
        {
            Element.Data("gigTilt", deg);
            Type.SetField(Element[0], "tilt", deg); // Mainly for SnapTo library
            Element.Plugin<IRot>().Rotate(new Dictionary("angle", deg));
            return this;
        }

        public Gig SetId(string id)
        {
            Id = id ?? Id;
            Element.Attribute("id", Id);
            return this;
        }

        public Gig Pos(Dictionary how)
        {
            Element.Plugin<Jewl>().Position(how);
            return this;
        }

        [AlternateSignature]
        public extern Gig Dim(int width);

        public Gig Dim(int width, int height)
        {
            Element.Width(width);
            if (Arguments.Length > 1)
                Element.Height(height);
            return this;
        }

        public Gig FromHtml(string html)
        {
            Content = jQuery.FromHtml(html).PrependTo(Element);
            return this;
        }

        public Gig FromElement(jQueryObject el)
        {
            Content = el;
            el.PrependTo(Element);
            Element.Data(GigClassName, this);
            return this;
        }

        private static readonly RegularExpression ExtractGigClassRx = new RegularExpression(@"<gigclass:\s*(.*)\s*/>", "g");

        public static jQueryObject ParseContent(string txt)
        {
            Script.Literal("{0}.lastIndex = 0", ExtractGigClassRx);
            string[] mx = ExtractGigClassRx.Exec(txt);
            if (mx != null && mx.Length > 1)
            {
                try
                {
                    return (jQueryObject) Script.Eval("new " + mx[1] + "().Content()");
                }
                catch (Exception ex)
                {
                    string s = ex.ToString();
                    return jQuery.FromHtml("<div>" + s + "</div>");
                }
            }
            return jQuery.FromHtml(txt);
        }

#pragma warning restore 108,114
    }

    public sealed class SlideData
    {
        // ReSharper disable InconsistentNaming
        public string build;
        public Dictionary css = new Dictionary();
        public string curate;
        public int embedGap;
        public Dictionary<string, GigData> gigs;
        public bool hasBackground;
        public int interval = 5000;
        public string load;
        public string loadCss;
        public int slide;
        public string style;
        // ReSharper restore InconsistentNaming
    }

    public sealed class GigData
    {
        // ReSharper disable InconsistentNaming
        public Dictionary attributes;
        public bool autosize;
        public string build;
        public string iclass;
        public string classNames = "";
        public string clusterId;
        public int cornerRadius;
        public Dictionary css = new Dictionary();
        public Dimension dim = new Dimension();
        public bool embedded;
        public bool floated;
        public string groupId;
        public bool hasHeight;
        public bool noCover;
        public string html;
        public string id = Formulas.NewId;
        public string iid;
        public string listType;
        public string load;
        // GigDataOffFix
        //public Pos off = new Pos();
        public Pos pos = new Pos();
        public string selecTo;
        public string parentId;
        public double tilt;
        public string type;
        public Dictionary<string, object> data;
        public Dictionary<string, string> help;
        public GigActions actions;
        // ReSharper restore InconsistentNaming

        public GigData(string showSelectTo)
        {
            selecTo = showSelectTo;
        }
    }

    public sealed class GigActions
    {
        public string paste;
        public string place;
    }

    public sealed class Pos
    {
        // ReSharper disable InconsistentNaming
        public int Left;
        public int Top;
        // ReSharper restore InconsistentNaming
    }

    public sealed class Dimension
    {
        // ReSharper disable InconsistentNaming
        public int height;
        public int width;
        // ReSharper restore InconsistentNaming
    }

    public abstract class GigShowConfig
    {
        public bool css;
        public bool doubleclick;
        public string inner;
        public bool rounding;
    }
}